#ifndef NODE_H_
#define NODE_H_

#include <Basic.hh>

enum NodeType
{
	DoublyNodeType
};

//
/**
 * \file Node.hh
 * \author  jsk <jsk.jinsubkim@gmail.com>
 * \version 1.0
 *
 * \class Node Node.hh
 *
 * 노드 간의 연결과 해제를 보장한다.
 * 
 * \warning
 * 
 * 노드를 제거하는 경우에 따로 unlink 메소드를 호출하지 않는다.
 */
class Node
{
public:
	/**
	 * \name generate
	 * 
	 * 노드를 생성한다.
	 * 
	 * \return 
	 * 
	 * 성공할 경우 RETURN_OK, 
	 * 실패할 경우 RETURN_OK가 아닌 값.
	 */
	static Node* generate(NodeType Type);
	
	/**
	 * \name linkLeft
	 * \param Node 연결될 노드.
	 * 
	 * 지정된 노드를 윈쪽에 연결한다.
	 * 
	 * \warning
	 * 
	 * 파라메터를 통해서 전달된 노드의 연결은 초기화 된다.
	 * 만약 연결에 실패하면 이전 연결 정보를 유지한다.
	 * 
	 * \return 
	 * 
	 * 성공할 경우 RETURN_OK, 
	 * 실패할 경우 RETURN_OK가 아닌 값.
	 */
	virtual ResultOf linkLeft(Node* Node) = 0;
	
	/**
	 * \name linkRight
	 * \param Node 연결될 노드.
	 * 
	 * 지정된 노드를 오른쪽에 연결한다.
	 * 
	 * \warning
	 * 
	 * 파라메터를 통해서 전달된 노드의 연결은 초기화 된다.
	 * 
	 * \return 
	 * 
	 * 성공할 경우 RETURN_OK, 
	 * 실패할 경우 RETURN_OK가 아닌 값.
	 */
	virtual ResultOf linkRight(Node* Node) = 0;
	
	/**
	 * \name unlink
	 * 
	 * 노드의 연결을 해제한다.
	 * 
	 * \return 
	 * 
	 * 성공할 경우 RETURN_OK, 
	 * 실패할 경우 RETURN_OK가 아닌 값.
	 */
	virtual ResultOf unlink() = 0;
	
	/**
	 * \name attach
	 * \param Object 노드와 연결될 오브젝트.
	 * 
	 * 노드와 결합되는 오브젝트.
	 * 
	 * \return 
	 * 
	 * 성공할 경우 RETURN_OK, 
	 * 실패할 경우 RETURN_OK가 아닌 값.
	 */
	virtual ResultOf attach(void* Object) = 0;
	
	/**
	 * \name setLeft
	 * \param Node 새로운 윈쪽 노드.
	 * 
	 * 윈쪽 노드를 변경한다.
	 * 만약 실패하면 윈쪽 노드는 변경되지 않는다.
	 * 
	 * \return 
	 * 
	 * 성공할 경우 RETURN_OK, 
	 * 실패할 경우 RETURN_OK가 아닌 값.
	 */
	virtual ResultOf setLeft(Node* Node) = 0;
	
	/**
	 * \name setRight
	 * \param Node 새로운 오른쪽 노드.
	 * 
	 * 오른쪽 노드를 변경한다.
	 * 만약 실패하면 오른쪽 노드는 변경되지 않는다.
	 * 
	 * \return 
	 * 
	 * 성공할 경우 RETURN_OK, 
	 * 실패할 경우 RETURN_OK가 아닌 값.
	 */
	virtual ResultOf setRight(Node* Node) = 0;
	
	/**
	 * \name tellObject
	 * 
	 * 노드의 데이터를 알려준다.
	 * 
	 * \return 
	 * 
	 * 데이터의 주소, 
	 * 데이터가 없을 경우 NULL.
	 */
	virtual void* tellObject() = 0;
	
	/**
	 * \name tellLeft
	 * 
	 * 윈쪽으로 연결된 노드를 알려준다.
	 * 
	 * \return 
	 * 
	 * 윈쪽에 연결된 노드가 있을 경우 해당 노드의 주소, 
	 * 연결된 노드가 없을 경우 NULL.
	 */
	virtual Node* tellLeft() = 0;
	
	/**
	 * \name tellRight
	 * 
	 * 오른쪽으로 연결된 노드를 알려준다.
	 * 
	 * \return 
	 * 
	 * 오른쪽에 연결된 노드가 있을 경우 해당 노드의 주소,
	 * 연결된 노드가 없을 경우 NULL.
	 */
	virtual Node* tellRight() = 0;
};

#endif //NODE_H_